package com.baiwei.vpnapi.service.impl;
import com.baiwei.vpnapi.dao.*;
import com.baiwei.vpnapi.entity.*;
import com.baiwei.vpnapi.entity.reqentity.UserCreateInput;
import com.baiwei.vpnapi.exception.AccountException;
import com.baiwei.vpnapi.exception.AuthException;
import com.baiwei.vpnapi.exception.BusinessEnum;
import com.baiwei.vpnapi.service.AccountService;
import com.baiwei.vpnapi.utils.AppUtils;
import com.baiwei.vpnapi.utils.JwtTokenUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.thymeleaf.util.StringUtils;

/**
 * @program: vpnapi
 * @description: 账号操作服务
 * @author: Mr. Stone
 * @create: 2020-02-25 07:11
 **/
@Service(value="acService")
public class AccountServiceImpl implements AccountService {

    private static Logger logger = LoggerFactory.getLogger(AccountServiceImpl.class);


    @Autowired
    private UserMapper userMapper;

    @Autowired
    private DeviceMapper deviceMapper;

    @Autowired
    private ChannelMapper channelMapper;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private RecommendMapper recommendMapper;

    @Autowired
    private UserPackageMapper userPackageMapper;

    @Autowired
    private VpnPackageMapper vpnPackageMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    /*
    * 发送短信返回通知类
    * */
    @Data
    public class SMSNotice {
        public String getRef() {
            return ref;
        }

        public void setRef(String ref) {
            this.ref = ref;
        }

        public Integer getStatus() {
            return status;
        }

        public void setStatus(Integer status) {
            this.status = status;
        }

        public Integer getReturn_code() {
            return return_code;
        }

        public void setReturn_code(Integer return_code) {
            this.return_code = return_code;
        }

        private String ref;
        private Integer status;
        private Integer return_code;
    }



    @Override
    @Transactional
    public Object userCreate(UserCreateInput info)
    {

        logger.info("register params:{}", info);
        String ipAddr = AppUtils.getIpAddr(request);
        /* 入参验证 */
        info.validation();
        /* 根据用户名查找是否存在同名用户 */
        String password = info.getPassword();
        QueryWrapper<VpnUser> wrapper = new QueryWrapper<>();
        VpnUser conUser = new VpnUser();
        conUser.setUsername(info.getUsername());
        wrapper.setEntity(conUser);
        VpnUser rUser = userMapper.selectOne(wrapper);
        System.out.println(rUser);
        if(rUser != null) {
            throw new AccountException(BusinessEnum.USER_REGISTER_EXIST);
        }
        /* 插入新建用户 */
        String platform = request.getHeader("platform");
        String version = request.getHeader("version");
        VpnUser insertUser = new VpnUser();
        insertUser.setUsername(info.getUsername());
        insertUser.setPassword(password);
        insertUser.setRegTime(new Date());
        insertUser.setIpAddr(ipAddr);
        insertUser.setCurPlatform(platform);
        insertUser.setRegVersion(version);
        String channelNo = info.getChannelNo();
        HashMap<String, String> channelInfoMap =  AppUtils.platToChannel();
        String channelNoLocal = channelInfoMap.get(platform);
        if(channelNo != null && channelNo.length() == 6) {
            ChannelInfo channelInfo = channelMapper.getChannelByChannelNo(channelNo);
            if(channelInfo != null) {
                insertUser.setChannelNo(channelNo);
            } else {
                insertUser.setChannelNo(channelNoLocal);
            }
        } else {
            insertUser.setChannelNo(channelNoLocal);

        }

        String inviteCode = info.getInviteCode();
        if(!StringUtils.isEmpty(inviteCode)) {
            insertUser.setUseTime(new Date());
            insertUser.setInviteBonusTime(3 * 60 * 60);
        }
        insertUser.setLoginIp(ipAddr);
        insertUser.setLoginVersion(version);
        insertUser.setLoginPlatform(platform);

        logger.info("insert user {}", insertUser);

        userMapper.insert(insertUser);
        logger.info("---------------{}", insertUser.getUserId());
        /* 如果是邀请码注册，添加邀请信息 */

        String device = request.getHeader("device");
        if(!StringUtils.isEmpty(inviteCode)){
            LambdaQueryWrapper<VpnUser> userLam = new QueryWrapper<VpnUser>()
                    .lambda().eq(VpnUser::getInviteCode, inviteCode);
            VpnUser inviteUser = userMapper.selectOne(userLam);
            if(inviteUser == null) {
                throw new AccountException(BusinessEnum.INVITE_CODE_ERROR);
            }
            if(inviteUser.getStatus().equals(0)) {
                throw new AccountException(BusinessEnum.INVITE_CODE_ERROR);
            }
            if(!StringUtils.isEmpty(device)) {
                LambdaQueryWrapper<VpnRecommend> recLam = new QueryWrapper<VpnRecommend>()
                        .lambda().eq(VpnRecommend::getDeviceToken, device)
                        .eq(VpnRecommend::getInviteUser, inviteUser.getUserId());
                VpnRecommend existVpnRec = recommendMapper.selectOne(recLam);
                if(existVpnRec != null) {
                    throw new AccountException(BusinessEnum.INVITE_EXIST_AT_SAMEDEVICE);
                }
            }
            // 奖励时间
            UserPackage qup = new UserPackage();
            qup.setUserId(insertUser.getUserId());
            qup.setOrderNo("00000000000");
            long dalta = 3 * 60 * 60 * 1000;
            long nowsamp = System.currentTimeMillis();
            long endsamp = System.currentTimeMillis() + dalta;
            Date startDate = new Date(nowsamp);
            Date endDate = new Date(endsamp);
            qup.setStartTime(startDate);
            qup.setEndTime(endDate);
            qup.setStatus(1);
            qup.setPackageId(vpnPackageMapper.getShareBonusPackageId());
            userPackageMapper.insert(qup);

            // 插入推荐记录
            VpnRecommend recommend = new VpnRecommend();
            recommend.setCreateTime(new Date());
            recommend.setInviteUser(inviteUser.getUserId());
            recommend.setInviteUserName(inviteUser.getUsername());
            recommend.setTargetUser(insertUser.getUserId());
            recommend.setTargetUserName(insertUser.getUsername());
            recommend.setDeviceToken(device);
            recommend.setStatus(0);
            recommendMapper.insert(recommend);
        }
        /* 生成token */
        Map<String,Object> tokenInfo = new HashMap<>();
        String token = jwtTokenUtil.doGenerateToken(tokenInfo, insertUser.getUserId().toString());
        /* 生成deviceid 客户端传入device则不需要创建 */
        String device_identity = request.getHeader("device");
        if(device_identity == null || device_identity.length() == 0) {
            device_identity = UUID.randomUUID().toString();
        }
        Map<String, String> res = new HashMap<>();
        res.put("token", token);
        res.put("device", device_identity);
        logger.info("register back: {}", res);
//        if(ipAddr != null && ipAddr.length() > 0) {
//            String timeStamp = String.valueOf(new Date().getTime() / 1000);
//            stringRedisTemplate.opsForValue().set("blk:" + ipAddr, timeStamp, 60 * 10, TimeUnit.SECONDS);
//        }
        return res;
    }

    @Override
    public Object userInfo() {
        String token = request.getHeader("Authorization");
        return jwtTokenUtil.getVpnUser(token);
    }

}
